(ns joy.web
  (:import (com.sun.net.httpserver HttpHandler HttpExchange HttpServer)
           (java.net InetSocketAddress HttpURLConnection)))

(defn new-server [port path handler]
  "创建一个新的服务器"
  ;; 创建一个绑定端口的套接字
  (doto (HttpServer/create (InetSocketAddress. port) 0)
    ;; 设置处理上下文
    (.createContext path handler)
    ;; 设置线程池
    (.setExecutor nil)
    (.start)))

;; 定义默认处理器
(defn default-handler [txt]
  (proxy [HttpHandler] []
    ;; exchange相当于一个交换器 请求和响应的交换
    (handle [exchange]
      ;; 设置http头
      (.sendResponseHeaders exchange HttpURLConnection/HTTP_OK 0)
      ;; 发送响应请求
      (doto (.getResponseBody exchange)
        (.write (.getBytes txt))
        (.close)))))

;; 制作一个创建处理器的函数
(defn make-handler-fn [fltr txt]
  ;; 返回一个处理器函数
  (fn [this exchange]
    ;; 读取txt中的全部bytes
    (let [b (.getBytes txt)]
      ;; 设置http头
      (-> exchange
          .getResponseHeaders
          (.set "Content-Type" "text/html"))
      (.sendResponseHeaders exchange
                            HttpURLConnection/HTTP_OK
                            0)
      ;; fltr钩子可以获取到响应对象的输出流
      (doto (fltr (.getResponseBody exchange))
        (.write b)
        (.close)))))

(defn change-message
  "可以改变输出的方法"
  ;; 注意过滤fltr identity 可以返回对象本身
  ([p txt] (change-message p identity txt))
  ([p fltr txt]
   (update-proxy p
                 {"handle" (make-handler-fn fltr txt)})))

(def server (new-server 8123 "/joy/hello"
                        (default-handler "Hello Cleveland")))